/**
 * 统一错误处理工具
 * 提供友好的错误提示和错误追踪
 */

import { Message, MessageBox, Notification } from 'element-ui'
import Logger from './logger'

/**
 * 错误类型枚举
 */
export const ErrorType = {
  NETWORK: 'NETWORK',           // 网络错误
  API: 'API',                   // API错误
  VALIDATION: 'VALIDATION',     // 验证错误
  PERMISSION: 'PERMISSION',     // 权限错误
  TIMEOUT: 'TIMEOUT',           // 超时错误
  UNKNOWN: 'UNKNOWN'            // 未知错误
}

/**
 * HTTP状态码对应的错误信息
 */
const HTTP_ERROR_MSG = {
  400: '请求参数错误',
  401: '登录已过期，请重新登录',
  403: '没有权限访问该资源',
  404: '请求的资源不存在',
  405: '请求方法不允许',
  408: '请求超时',
  500: '服务器内部错误',
  502: '网关错误',
  503: '服务暂不可用',
  504: '网关超时'
}

/**
 * 业务错误码对应的错误信息
 */
const BUSINESS_ERROR_MSG = {
  1001: '用户名或密码错误',
  1002: '验证码错误或已过期',
  1003: '账号已被锁定',
  1004: '账号不存在',
  2001: '提交失败，请稍后重试',
  2002: '数据已被删除',
  2003: '数据已存在',
  3001: '审核失败',
  3002: '状态异常，无法操作',
  4001: '余额不足',
  4002: '提现金额超出限制'
}

class ErrorHandler {
  /**
   * 处理API错误
   * @param {Error} error - 错误对象
   * @param {Object} options - 配置选项
   */
  static handleApiError(error, options = {}) {
    const {
      showMessage = true,        // 是否显示错误提示
      messageType = 'message',   // 提示类型: 'message' | 'notification' | 'alert'
      logError = true,           // 是否记录错误日志
      customHandler = null       // 自定义错误处理函数
    } = options

    // 记录错误日志
    if (logError) {
      Logger.error('API错误:', error)
    }

    // 自定义错误处理
    if (customHandler && typeof customHandler === 'function') {
      return customHandler(error)
    }

    // 提取错误信息
    const errorInfo = this.parseError(error)

    // 显示错误提示
    if (showMessage) {
      this.showError(errorInfo.message, messageType, errorInfo.type)
    }

    return errorInfo
  }

  /**
   * 解析错误信息
   * @param {Error} error - 错误对象
   * @returns {Object} 错误信息对象
   */
  static parseError(error) {
    // 网络错误
    if (!error.response) {
      return {
        type: ErrorType.NETWORK,
        message: error.message === 'Network Error'
          ? '网络连接失败，请检查网络设置'
          : '网络请求异常，请稍后重试',
        originalError: error
      }
    }

    const { status, data } = error.response

    // HTTP状态码错误
    if (status && HTTP_ERROR_MSG[status]) {
      return {
        type: ErrorType.API,
        code: status,
        message: HTTP_ERROR_MSG[status],
        originalError: error
      }
    }

    // 业务错误码
    if (data && data.code && BUSINESS_ERROR_MSG[data.code]) {
      return {
        type: ErrorType.API,
        code: data.code,
        message: BUSINESS_ERROR_MSG[data.code],
        originalError: error
      }
    }

    // 后端返回的错误信息
    if (data && data.msg) {
      return {
        type: ErrorType.API,
        code: data.code,
        message: data.msg,
        originalError: error
      }
    }

    // 超时错误
    if (error.code === 'ECONNABORTED' || error.message.includes('timeout')) {
      return {
        type: ErrorType.TIMEOUT,
        message: '请求超时，请稍后重试',
        originalError: error
      }
    }

    // 未知错误
    return {
      type: ErrorType.UNKNOWN,
      message: '操作失败，请稍后重试',
      originalError: error
    }
  }

  /**
   * 显示错误提示
   * @param {String} message - 错误信息
   * @param {String} type - 提示类型
   * @param {String} errorType - 错误类型
   */
  static showError(message, type = 'message', errorType) {
    const options = {
      message,
      type: 'error',
      duration: 3000
    }

    switch (type) {
      case 'message':
        Message.error(options)
        break

      case 'notification':
        Notification.error({
          title: this.getErrorTitle(errorType),
          message,
          duration: 4000
        })
        break

      case 'alert':
        MessageBox.alert(message, '错误提示', {
          confirmButtonText: '知道了',
          type: 'error'
        })
        break

      default:
        Message.error(options)
    }
  }

  /**
   * 获取错误标题
   * @param {String} errorType - 错误类型
   * @returns {String} 错误标题
   */
  static getErrorTitle(errorType) {
    const titles = {
      [ErrorType.NETWORK]: '网络错误',
      [ErrorType.API]: 'API错误',
      [ErrorType.VALIDATION]: '验证错误',
      [ErrorType.PERMISSION]: '权限错误',
      [ErrorType.TIMEOUT]: '超时错误',
      [ErrorType.UNKNOWN]: '未知错误'
    }
    return titles[errorType] || '错误'
  }

  /**
   * 处理表单验证错误
   * @param {Object} errors - 验证错误对象
   * @param {String} formRef - 表单ref
   */
  static handleValidationError(errors, formRef) {
    if (errors && typeof errors === 'object') {
      const firstError = Object.values(errors)[0]
      if (Array.isArray(firstError) && firstError.length > 0) {
        Message.warning({
          message: firstError[0],
          duration: 2000
        })
      }
    }

    Logger.warn('表单验证失败:', errors)
  }

  /**
   * 处理权限错误
   * @param {String} message - 错误信息
   */
  static handlePermissionError(message = '您没有权限执行此操作') {
    Message.warning({
      message,
      duration: 2000
    })

    Logger.warn('权限错误:', message)
  }

  /**
   * 确认操作提示
   * @param {String} message - 提示信息
   * @param {String} title - 标题
   * @param {Object} options - 配置选项
   * @returns {Promise}
   */
  static confirm(message, title = '确认操作', options = {}) {
    return MessageBox.confirm(message, title, {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
      ...options
    })
  }

  /**
   * 成功提示
   * @param {String} message - 提示信息
   * @param {Number} duration - 显示时长
   */
  static success(message, duration = 2000) {
    Message.success({
      message,
      duration
    })
  }

  /**
   * 警告提示
   * @param {String} message - 提示信息
   * @param {Number} duration - 显示时长
   */
  static warning(message, duration = 2000) {
    Message.warning({
      message,
      duration
    })
  }

  /**
   * 信息提示
   * @param {String} message - 提示信息
   * @param {Number} duration - 显示时长
   */
  static info(message, duration = 2000) {
    Message.info({
      message,
      duration
    })
  }

  /**
   * Loading提示
   * @param {String} message - 提示信息
   * @returns {Object} Loading实例
   */
  static loading(message = '加载中...') {
    return Message({
      message,
      type: 'info',
      duration: 0,
      iconClass: 'el-icon-loading'
    })
  }
}

/**
 * 便捷导出
 */
export const handleApiError = ErrorHandler.handleApiError.bind(ErrorHandler)
export const handleValidationError = ErrorHandler.handleValidationError.bind(ErrorHandler)
export const handlePermissionError = ErrorHandler.handlePermissionError.bind(ErrorHandler)
export const confirm = ErrorHandler.confirm.bind(ErrorHandler)
export const success = ErrorHandler.success.bind(ErrorHandler)
export const warning = ErrorHandler.warning.bind(ErrorHandler)
export const info = ErrorHandler.info.bind(ErrorHandler)
export const loading = ErrorHandler.loading.bind(ErrorHandler)

export default ErrorHandler

